import { _decorator, Animation, AnimationState, AudioClip, AudioSource, Collider2D, Component, Contact2DType, find, IPhysics2DContact, Node, RigidBody2D, Toggle, UIOpacity, v2, Vec2 } from 'cc';
import { MainLlogic } from './MainLlogic';
const { ccclass, property } = _decorator;

@ccclass('Player')
export class Player extends Component {

    @property({type:Node})
    private control:Node = null

    /**
     * 主角跳跃高度
     */
    @property({type:Number})
    private jumpHeight:number = 10

     /**
     * 主角基础移速
     */
     @property({type:Number})
     private speed:number = 20

      /**
     * 主角跳跃段数限制
     */
      @property({type:Number})
      private jumpLimit:number = 2
    

    private playerVelocity:Vec2 = new Vec2(0,0)
    /**
     * 动画组件
     */
    playerani:Animation

    /**
     * 动画
     */
    anima:string = ''

    /**
     *  主角状态
     * 1：跑
     * 2：跳跃
     * 3：跳跃落地缓冲
     * 4：死亡
     * 5:复活
     */
    playerstate:number = 0

    isatk:boolean = false


    playerAS:AudioSource = null

    @property({type:AudioClip})
    private jumpclip:AudioClip = null

    atkInterval:number = 300

    lefttouch:boolean = false

    righttouch:boolean = false

    //上升气流
    updraft:boolean = false

    //下坠
    falling:boolean = false


    start() {

        let left = this.control.getChildByName('Left')
        let right = this.control.getChildByName('Right')

        left.on(Node.EventType.TOUCH_START,this.leftTouchStart,this)
        left.on(Node.EventType.TOUCH_END,this.leftTouchEnd,this)
        left.on(Node.EventType.TOUCH_CANCEL,this.leftTouchEnd,this)

        right.on(Node.EventType.TOUCH_START,this.rightTouchStart,this)
        right.on(Node.EventType.TOUCH_END,this.rightTouchEnd,this)
        right.on(Node.EventType.TOUCH_CANCEL,this.rightTouchEnd,this)

        this.node.getComponent(Collider2D).on(Contact2DType.BEGIN_CONTACT,this.onBeginContact,this)
        this.playerani = this.node.getComponent(Animation)
        this.playerani.on(Animation.EventType.FINISHED,this.onAnimationEvent,this)

        this.playerAS = this.node.getComponent(AudioSource)
        this.setani('player_ldle')
    }

    getMode(){
        this.updraft = find('Canvas/MainLogic/CurtainStart/updraft/Toggle').getComponent(Toggle).isChecked        
        this.falling = find('Canvas/MainLogic/CurtainStart/falling/Toggle').getComponent(Toggle).isChecked
    }

    jumpup(){
        this.playerVelocity = this.node.getComponent(RigidBody2D).linearVelocity
        this.playerVelocity.y = this.jumpHeight
        this.node.getComponent(RigidBody2D).linearVelocity = this.playerVelocity
    }
    jumpdown(){
        this.playerVelocity = this.node.getComponent(RigidBody2D).linearVelocity
        this.playerVelocity.y = -this.jumpHeight
        this.node.getComponent(RigidBody2D).linearVelocity = this.playerVelocity
    }

    leftTouchStart(){
        if(this.node.getParent().getComponent(MainLlogic).isRun){
            if(!this.node.getParent().getComponent(MainLlogic).gameover){
                if(this.playerstate == 1||this.playerstate == 2){
                    if(!this.updraft){
                        if(this.jumpLimit>0){
                            this.jumpup()
                            this.jumpLimit--
                            this.playerAS.playOneShot(this.jumpclip,0.1)
                        }
                        this.playerstate = 2
                    }else{
                        this.playerstate = 2
                        this.lefttouch = true
                    }
                }
            }
        }
    }

    leftTouchEnd(){
        this.lefttouch = false
    }

    rightTouchStart(){

        if(this.node.getParent().getComponent(MainLlogic).isRun){
            if(!this.node.getParent().getComponent(MainLlogic).gameover){
                if(this.playerstate != 5&&this.playerstate != 4){
                    if(!this.falling){
                        if(this.atkInterval >= 300){
                            this.setani('player_atk')
                            this.isatk = true
                            this.atkInterval = 0
                        }
                    }else{
                        this.jumpdown()
                        this.lefttouch = false
                    }
                    // this.jumpdown()
                }
            }
        }
        
    }

    rightTouchEnd(){
        
    }

    log1000(x){
        return Math.atan(x)*2/Math.PI*1.3
    }
    revive(){
        this.playerstate = 5
        this.setani('player_revive')
    }

    reset(){
        this.node.getParent().getComponent(MainLlogic).reset()
        this.playerstate = 0
        this.setani('player_ldle')
        this.jumpLimit = 2
    }

    setani(anima){ 
        if(this.isatk)return
        if(this.anima == anima) return

        this.anima = anima
        this.playerani.play(this.anima)
    }

    onAnimationEvent(type: Animation.EventType, state: AnimationState) {

        if(state.name == 'player_jump_end'){
            this.playerstate = 1
        }

        if(state.name == 'player_revive'){
            this.reset()
        }

        if(state.name == 'player_atk'){
            this.isatk = false
            this.node.getChildByName('atk').getComponent(UIOpacity).opacity = 0
        }
        
    }

    atk(){
        this.node.getChildByName('atk').getComponent(UIOpacity).opacity = 255
    }

    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null){
        if(!this.node.getParent().getComponent(MainLlogic).gameover){
            //暂定为跳跃以及与怪物碰撞判定
            if(selfCollider.tag == 1){
                if(otherCollider.group == 8&&this.anima != 'player_atk'){
                    this.node.getParent().getComponent(MainLlogic).gameOver()
                    this.node.getComponent(RigidBody2D).linearVelocity = v2(0,0)
                    this.playerstate = 4
                    this.node.getParent().getComponent(MainLlogic).createStartScreen()
                    console.log('game over')
                }
                if(otherCollider.group == 4&&this.playerstate == 2){
                    this.jumpLimit = 2
                    this.playerstate = 3
                }
            }
        }
        
    }

    update(deltaTime: number) {
        if(this.playerstate != 5){
            if(!this.node.getParent().getComponent(MainLlogic).gameover){
                if(this.node.getParent().getComponent(MainLlogic).isRun){
                    if(this.lefttouch&&this.updraft){
                        this.jumpup()
                    }
                    this.playerVelocity = this.node.getComponent(RigidBody2D).linearVelocity
                    this.playerVelocity.x = this.speed*(1+this.log1000(this.node.position.x/40000))
                    this.node.getComponent(RigidBody2D).linearVelocity = this.playerVelocity
                    if(this.playerstate == 1){
                        this.setani('player_run')
                    }else if(this.playerstate == 2){
                        if(this.playerVelocity.y > 0){
                            this.setani('player_jump_up')
                        }else{
                            this.setani('player_jump_down')
                        }
                    }else if(this.playerstate == 3){
                        this.setani('player_jump_end')
                    }else if(this.playerstate == 0){
                        this.playerstate = 1
                    } 
                }else{
                    this.node.getComponent(RigidBody2D).linearVelocity = v2(0,0)
                }

            }else{
                this.setani('player_dead')
            }
        }
        if(this.playerstate == 0){
            this.setani('player_idle')
        }
        if(this.atkInterval<300){
            this.atkInterval++
        }
    }
}


